//
//  CameraView+Api.swift
//  WatermarkCamera
//
//  Created by AxcLogo on 4/7/2024.
//

import UIKit
import AxcBedrock

// MARK: - CameraView + CameraApi

extension CameraView: CameraApi {
    // MARK: - 相机方法

    // MARK: 采集

    /// 开始采集
    func beginCapture() {
        camera.beginCapture()
    }

    /// 停止采集
    func endCapture() {
        camera.endCapture()
    }

    /// 暂停采集
    func pauseCapture() {
        camera.pauseCapture()
    }

    /// 重新采集
    func resumeCapture() {
        camera.resumeCapture()
    }

    /// 是否正在运行
    func isRunning() -> Bool {
        return camera.isRunning()
    }

    /// 获取采集会话
    func captureSession() -> AVCaptureSession {
        return camera.captureSession()
    }

    /// 设置采集清晰度
    /// - Parameter articulation: 采集质量
    func setCaptureArticulation(_ articulation: AVCaptureSession.Preset) {
        camera.setCaptureArticulation(articulation)
    }

    /// 获取采集清晰度
    func captureArticulation() -> AVCaptureSession.Preset {
        return camera.captureArticulation()
    }

    // MARK: 输出模式

    /// 设置输出图片朝向
    /// - Parameter outputImageOrientation: 朝向
    func setOutputImageOrientation(_ outputImageOrientation: UIInterfaceOrientation) {
        camera.setOutputImageOrientation(outputImageOrientation)
    }

    /// 获取输出图片朝向
    func outputImageOrientation() -> UIInterfaceOrientation {
        return camera.outputImageOrientation()
    }

    /// 设置前置水平镜像
    /// - Parameter horizontallyMirror: 水平镜像
    func setHorizontallyFrontMirror(_ isMirror: Bool) {
        camera.setHorizontallyFrontMirror(isMirror)
    }

    /// 获取是否开启前置水平镜像
    func horizontallyFrontMirror() -> Bool {
        return camera.horizontallyFrontMirror()
    }

    /// 设置后置水平镜像
    /// - Parameter horizontallyMirror: 水平镜像
    func setHorizontallyBackMirror(_ isMirror: Bool) {
        camera.setHorizontallyBackMirror(isMirror)
    }

    /// 获取是否开启后置水平镜像
    func horizontallyBackMirror() -> Bool {
        return camera.horizontallyBackMirror()
    }

    // MARK: 相机切换

    /// 设置前后相机
    /// - Parameter position: 位置前后
    func setPosition(_ position: Camera.Position) {
        camera.setPosition(position)
    }

    /// 获取当前前后相机
    func position() -> Camera.Position {
        return camera.position()
    }

    /// 翻转相机
    func rotateCamera() {
        camera.rotateCamera()
    }

    /// 摄像头即将切换
    func setWillRotateCameraBlock(_ block: @escaping AxcBlock.OneParam<Camera.Position>) {
        camera.setWillRotateCameraBlock(block)
    }

    /// 摄像头已经完成切换
    func setDidRotateCameraBlock(_ block: @escaping AxcBlock.OneParam<Camera.Position>) {
        camera.setDidRotateCameraBlock(block)
    }

    // MARK: 镜头相关

    /// 设置缩放长焦短焦
    /// - Parameter factor: 缩放指数
    func setZoomFactor(_ factor: CGFloat) {
        camera.setZoomFactor(factor)
    }

    /// 获取缩放指数
    func zoomFactor() -> CGFloat {
        return camera.zoomFactor()
    }

    /// 设置对焦点位
    /// - Parameter focusPoint: 对焦点，x，y取值0-1
    func setFoucsPoint(_ focusPoint: CGPoint) {
        camera.setFoucsPoint(focusPoint)
    }

    /// 设置对焦，点击的对焦点位
    /// - Parameter tapPoint: 对焦点，x，y取值点击点
    func setTouchFoucsPoint(_ tapPoint: CGPoint) {
        let size = bounds.size

        let focusPoint = CGPoint(x: tapPoint.y / size.height,

                                 y: 1 - tapPoint.x / size.width)

        camera.setFoucsPoint(focusPoint)
    }

    /// 设置连续自动对焦
    func setContinuousAutoFocus() {
        camera.setContinuousAutoFocus()
    }

    /// 设置闪光灯模式
    /// - Parameter flashMode: 模式
    func setFlashMode(_ flashMode: Camera.FlashMode) {
        camera.setFlashMode(flashMode)
    }

    /// 是否有手电筒功能
    func hasTorch() -> Bool {
        return camera.hasTorch()
    }

    /// 是否有闪光灯功能
    func hasFlash() -> Bool {
        return camera.hasFlash()
    }
}

// MARK: - 画面渲染

extension CameraView {
    // MARK: 画幅调整

    /// 设置画幅比
    func setAspectRatio(_ aspectRatio: Eyepiece.AspectRatio) {
        eyepiece.setAspectRatio(aspectRatio)
    }

    /// 获取画幅比
    func aspectRatio() -> Eyepiece.AspectRatio {
        return eyepiece.aspectRatio()
    }

    // MARK: 画面曝光

    /// 设置画面曝光
    func setExposure(_ bias: CGFloat) {
        eyepiece.setExposure(bias)
    }

    /// 最大曝光
    func maxExposure() -> CGFloat {
        return 10
    }

    /// 最小曝光
    func minExposure() -> CGFloat {
        return -10
    }

    // MARK: 画面填充

    /// 设置填充模式
    /// - Parameter fillMode: 填充模式
    func setFillMode(_ fillMode: PreviewView.FillMode) {
        previewView.setFillMode(fillMode)
    }

    /// 获取填充模式
    func fillMode() -> PreviewView.FillMode {
        return previewView.fillMode()
    }
}

// MARK: - 滤镜方法

extension CameraView {
    // MARK: 滤镜增

    /// 追加滤镜
    /// - Parameter filter: 滤镜
    func appendFilter(_ filter: BaseFilter) {
        eyepiece.appendFilter(filter)
    }

    /// 插入滤镜
    /// - Parameters:
    ///   - filter: 滤镜
    ///   - index: 索引
    func insertFilter(_ filter: BaseFilter, at index: Int) {
        eyepiece.insertFilter(filter, at: index)
    }

    // MARK: 滤镜删

    /// 移除滤镜
    /// - Parameter index: 索引
    func removeFilter(at index: Int) {
        eyepiece.removeFilter(at: index)
    }

    /// 移除所有滤镜
    func removeAllFilter() {
        eyepiece.removeAllFilter()
    }

    // MARK: 滤镜改

    /// 移动滤镜顺序
    /// - Parameters:
    ///   - index: 从第几个索引
    ///   - toIndex: 到第几个索引
    func moveFilter(form index: Int, to toIndex: Int) {
        eyepiece.moveFilter(form: index, to: toIndex)
    }

    /// 修改滤镜
    /// - Parameters:
    ///   - filter: 滤镜
    ///   - index: 索引
    func replaceFilter(_ newFilter: BaseFilter, at index: Int) {
        eyepiece.replaceFilter(newFilter, at: index)
    }

    /// 交换两个滤镜的顺序
    /// - Parameters:
    ///   - index: 从第几个索引
    ///   - toIndex: 到第几个索引
    func exchangeFilter(form index: Int, to toIndex: Int) {
        eyepiece.exchangeFilter(form: index, to: toIndex)
    }

    /// 反转所有滤镜顺序
    func reversedAllFilter() {
        eyepiece.reversedAllFilter()
    }

    // MARK: 滤镜查

    /// 获取滤镜
    /// - Parameter index: 索引
    /// - Returns: 滤镜
    func filter<FT: BaseFilter>(at index: Int) -> FT? {
        return eyepiece.filter(at: index)
    }

    /// 滤镜数量
    func filterCount() -> Int {
        return eyepiece.filterCount()
    }
}

// MARK: - 水印方法

extension CameraView {
    // MARK: 增

    /// 添加水印图片
    /// - Parameters:
    ///   - image: 水印图片
    ///   - blendMode: 混合模式
    func appendWatermark(image: UIImage) {
        eyepiece.appendWatermark(image: image)
    }

    func appendElementWatermark(view: UIView) {
        eyepiece.appendElementWatermark(view: view)
    }

    /// 插入水印图片
    /// - Parameters:
    ///   - image: 水印图片
    ///   - blendMode: 混合模式
    ///   - index: 索引
    func insterWatermark(image: UIImage, at index: Int) {
        eyepiece.insterWatermark(image: image, at: index)
    }

    // MARK: 删

    /// 移除水印
    /// - Parameter index: 索引
    func removeWatermark(at index: Int) {
        eyepiece.removeWatermark(at: index)
    }

    /// 移除所有水印
    func removeAllWatermark() {
        eyepiece.removeAllWatermark()
    }

    // MARK: 改

    /// 移动水印顺序
    /// - Parameters:
    ///   - index: 从第几个索引
    ///   - toIndex: 到第几个索引
    func moveWatermark(form index: Int, to toIndex: Int) {
        eyepiece.moveWatermark(form: index, to: toIndex)
    }

    /// 更新水印图片
    /// - Parameters:
    ///   - image: 图片
    ///   - index: 索引
    func replaceWatermark(image: UIImage, at index: Int) {
        eyepiece.replaceWatermark(image: image, at: index)
    }

    /// 交换两个水印的顺序
    /// - Parameters:
    ///   - index: 从第几个索引
    ///   - toIndex: 到第几个索引
    func exchangeWatermark(form index: Int, to toIndex: Int) {
        eyepiece.exchangeWatermark(form: index, to: toIndex)
    }

    /// 反转所有水印顺序
    func reversedAllWatermark() {
        eyepiece.reversedAllWatermark()
    }
}

// MARK: - 写入终端

extension CameraView {
    /// 设置写入清晰度
    /// - Parameter writerArticulation: 清晰度
    func setWriterArticulation(_ writerArticulation: VideoBuffer.Articulation) {
        _writerArticulation = writerArticulation
    }

    /// 获取写入清晰度
    func writerArticulation() -> VideoBuffer.Articulation {
        return _writerArticulation
    }
}

// MARK: - 采集终端

extension CameraView {
    // MARK: 图片

    /// 采集某一时刻下的图片
    /// - Parameters:
    ///   - articulation: 清晰度
    ///   - aspectRatio: 画幅比
    ///   - block: 回调
    func collectImage(_ block: @escaping AxcBlock.OneParam<UIImage>) {
        imageWriter.collectImage(articulation: _writerArticulation,

                                 aspectRatio: eyepiece.aspectRatio(),

                                 block: block)
    }

    // MARK: 照片

    /// 采集照片
    /// - Parameters:
    ///   - gpuFilter: 滤镜节点
    ///   - block: 回调
    func collectPhoto(gpuFilter: GPUFilter,

                      block: @escaping AxcBlock.OneParam<UIImage>) {
        camera.collectPhoto(gpuFilter: gpuFilter, block: block)
    }

    /// 采集照片
    /// - Parameters:
    ///   - node: 节点
    ///   - block: 回调
    func collectPhoto(_ node: Eyepiece.CollectNode = .lastOutputNode,

                      block: @escaping AxcBlock.OneParam<UIImage>) {
        guard let gpuFilter = eyepiece.outputNode(node) else { return }

        camera.collectPhoto(gpuFilter: gpuFilter, block: block)
    }

    // MARK: 视频

    /// 开始采集视频
    /// - Parameters:
    ///   - fileUrl: 文件存储地址
    ///   - encodingLiveVideo: 对视频进行编码
    ///   - shouldCollectAudio: 对音频进行采集
    func beginCollectVideo(fileUrl: URL,

                           orientation: VideoWriter.Orientation = .orientation(.portrait),

                           encodingLiveVideo: Bool = true,

                           shouldCollectAudio: Bool = true) {
        videoWriter.beginCollectVideo(fileUrl: fileUrl,

                                      orientation: orientation,

                                      articulation: _writerArticulation,

                                      aspectRatio: eyepiece.aspectRatio(),

                                      encodingLiveVideo: encodingLiveVideo,

                                      shouldCollectAudio: shouldCollectAudio)
    }

    /// 暂停采集视频
    func pauseCollectVideo(_ finishBlock: @escaping AxcBlock.Empty) {
        videoWriter.pauseCollectVideo(finishBlock)
    }

    /// 继续采集视频
    func continueCollectVideo() {
        videoWriter.continueCollectVideo()
    }

    /// 停止采集视频
    /// - Parameter block: 回调
    func endCollectVideo(_ block: @escaping AxcBlock.OneParam<URL>) {
        videoWriter.endCollectVideo(block)
    }

    // MARK: 流

    /// 开始采集流
    /// - Parameters:
    ///   - articulation: 清晰度
    ///   - aspectRatio: 画幅比
    ///   - block: 回调
    func beginCollectVideoBuffer(_ block: @escaping AxcBlock.OneParam<CVBuffer>) {
        videoBuffer.beginCollectVideoBuffer(articulation: _writerArticulation,

                                            aspectRatio: eyepiece.aspectRatio(),

                                            block: block)
    }

    /// 停止采集流
    func endCollectVideoBuffer() {
        videoBuffer.endCollectVideoBuffer()
    }
}
